﻿using UnityEngine;
using System.Collections;
using System.IO;
using UnityEditor;

[ExecuteInEditMode]
public class ChangeShader : MonoBehaviour {

    private static string _EditorResourcePath = "/FunctionShader/Sources/Shaders/Resources/";
    public string filename = "Function.shader";
    public string equation = "sin(x)";
    public GameObject DisplayObject;
    public Color MainColor;
    public Color LineColor;
    public Color WaterColor;
    public float LineWidth;
    public float WaterHeight;
    public float WaterRange;

    public bool UpdateFunction = false;

	// Use this for initialization
	void Start () {
        DisplayObject = this.gameObject;
	}

    void Update()
    {
        if(UpdateFunction)
        {
            UpdateShader();
            UpdateFunction = false;
        }
    }

    void UpdateShader()
    {
        string shader = LoadShaderFileToString();
        DisplayObject.renderer.sharedMaterial= WriteToFile(shader);
        DisplayObject.renderer.sharedMaterial.SetVector("_ColorMain", MainColor);
        DisplayObject.renderer.sharedMaterial.SetVector("_ColorLine", LineColor);
        DisplayObject.renderer.sharedMaterial.SetVector("_ColorWater", WaterColor);
        DisplayObject.renderer.sharedMaterial.SetFloat("_LineWidth", LineWidth);
        DisplayObject.renderer.sharedMaterial.SetFloat("_WaterHeight", WaterHeight);
        DisplayObject.renderer.sharedMaterial.SetFloat("_WaterRange", WaterRange);
    }

    string LoadShaderFileToString()
    {
        StreamReader sr = new StreamReader(Application.dataPath + _EditorResourcePath + filename);
        string line = sr.ReadToEnd();

        int pos = line.IndexOf("eqn =") + "eqn =".Length;

        //index of newLine
        int newLine = pos;
        bool found = false;
        while(!found)
        {
            newLine++;
            found = line[newLine] == ';';
        }

        line = line.Remove(pos, newLine - pos);
        line = line.Insert(pos, equation);

        return line;
    }

    Material WriteToFile(string shaderString)
    {
        Directory.CreateDirectory(Application.dataPath + _EditorResourcePath);
        File.WriteAllText(Application.dataPath + _EditorResourcePath + "/FunctionRuntime.shader", shaderString);
        Shader currentShader = Resources.Load("FunctionRuntime") as Shader;
        var path = AssetDatabase.GetAssetPath(currentShader);
        AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
        Material m = new Material(currentShader);
        return m;
    }
}
